<!--
 * @Author: Liz.Zheng
 * @Date: 2021-12-03 10:09:27
 * @LastEditTime: 2023-02-16 10:18:22
 * @LastEditors: 郑亚莉 zhengyali@shequ.life
 * @Description: 费用条款
 * @Motto: Write the code. Change the world.
-->
<template>
  <div class="fee-clause">
    <section>
      <a-tabs
        v-model:activeKey="activeKey"
        hide-add
        type="editable-card"
        @edit="onPaneEdit"
      >
        <template #rightExtra>
          <a-dropdown :trigger="['click']">
            <a-button type="primary" size="small">
              <template #icon>
                <PlusOutlined />
              </template>
              条款
            </a-button>
            <template #overlay>
              <a-menu>
                <a-menu-item
                  v-for="clause of clauseList"
                  :key="clause.id"
                  @click="addPaneClick(clause)"
                >
                  {{ clause.name }}
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </template>
        <a-tab-pane
          v-for="pane in dataList"
          :key="pane.key"
          :tab="pane.name"
          :closable="dataList.length > 1"
          forceRender
        >
          <pane-content
            :content="pane"
            :contentTrigger="contentTrigger"
            @success="handleValidateSuccess"
            @fail="handleValidateFail"
          />
        </a-tab-pane>
      </a-tabs>
    </section>
  </div>
</template>

<script>
import moment from "moment";
import {
  computed,
  defineComponent,
  reactive,
  ref,
  watch,
  toRefs,
  toRaw,
  nextTick,
} from "vue";
import PaneContent from "./modules/PaneContent.vue";
import { PlusOutlined } from "@ant-design/icons-vue";
import { Form, message } from "ant-design-vue";
import store from "../../../store";
import request from "../../../common/utils/request";
import { useRoute } from "vue-router";
import utils from "@/common/utils/utils";
import _ from "lodash";

export default defineComponent({
  name: "ContractFeeClause",
  props: {
  },
  components: { PlusOutlined, PaneContent },
  setup(props, context) {
    // tab页
    const dataList = ref([]);
    const activeKey = ref("default");
    const haveBeenInside = ref(false); // 实时保存草稿 初始化的不保存 进来过才保存
    const isDraftFirst = ref(false);

    const useDraft = computed(() => store.getters.useDraft);
    const haveDraft = ref(false);

    const removePaneItem = (key) => {
      const index = dataList.value.findIndex((item) => item.key == key);
      if (activeKey.value == dataList.value[index].key) {
        activeKey.value = dataList.value[index - 1]
          ? dataList.value[index - 1].key
          : dataList.value[0].key;
      }

      // 删除条款时，需要把条款中已选择的房间释放
      let { checkedHouse, attribute, clause_id } = dataList.value[index];
      console.log(checkedHouse, attribute);
      if (checkedHouse && checkedHouse.length > 0) {
        for (let i = 0; i < checkedHouse.length; i++) {
          store.dispatch("SetPaneCheckedRoom", {
            type: "remove",
            roomIds: checkedHouse[i].id,
            clauseId: clause_id,
          });
        }
      }

      store.dispatch("SetClauseContent", {
        type: "reduce",
        content: dataList.value[index],
      });
      dataList.value.splice(index, 1);
    };
    let count = 0;

    // 单楼宇 新增条款
    const addPaneItem = (clause, setActiveKey = true) => {
      const allRoomList = store.getters.checkedRoomList;
      let item = { ...clause, clause_id: clause.id };
      const existIndex = dataList.value.findIndex(
        (item) => item.attribute == clause.attribute
      );
      if (existIndex > -1) {
        count++;
        item.key = clause.attribute + "_" + count;
      } else {
        item.key = clause.attribute + "_default";
      }
      item.title = clause.name;

      const goNext = (item) => {
        if (setActiveKey || !dataList.value.length) {
          activeKey.value = item.key;
        }
        dataList.value.push(item);
      };
      store
        .dispatch("SetClauseContent", { type: "add", content: item })
        .then(() => {
          const clauseTab = store.getters.clauseTabCount[item.clause_id];
          console.log("---------clauseTab", clauseTab);
          if (!clauseTab || clauseTab.count == 1) {
            item.checkedHouse = [...allRoomList];
            store.dispatch("SetPaneCheckedRoom", {
              type: "add",
              clauseId: item.clause_id,
              roomIds: item.checkedHouse.map((it) => it.id),
            });
            goNext(item);
          } else {
            store
              .dispatch("GetPaneCheckedRoom", item.clause_id)
              .then((result) => {
                item.checkedHouse = _.cloneDeep(allRoomList).filter((v) => !(result?.checkedIds || []).includes(v.id));
                goNext(item);
              });
          }

        });
    };
    const onPaneEdit = (targetKey) => {
      removePaneItem(targetKey);
    };

    watch(
      () => store.getters.editContractId,
      (id, preId) => {
        if (id && !preId) {
          getPaneList(id);
        }
      }
    );

    // 自定义模板内容
    const tplContent = computed(() => store.getters.tplContent);

    // 是否跨楼宇选择
    const multiBuild = computed(() => store.getters.multiBuild);

    const detailList = ref([]);
    const getPaneList = (id) => {
      const { feeClause } = store.getters.addFormData;
      // store.dispatch("ClearClauseContent");
      if (id && feeClause.expense_clause && feeClause.expense_clause.length) {
        // 回显
        request
          .get("/org", "/create/contractDetail", {
            id,
          })
          .then((res) => {
            detailList.value = res.data.map((v) => {
              let info = clauseList.value.find((item) => item.id == v.clause_id);
              if (info) {
                v.use_bond = info.use_bond;
                v.use_discount = info.use_discount;
                v.use_incr = info.use_incr;
                v.use_lease = info.use_lease;
                v.cost_type_txt = info.cost_type_txt;
                v.cost_type = info.cost_type;
                v.cost_type_name = info.cost_type_name;
              }
              return v;
            });
          });
      } else {
        // 新增
        if (clauseList.value.length && !isDraftFirst.value) {
          store.dispatch("ClearClauseContent").then((res) => {
            if (tplContent.value && tplContent.value.id) {
              // 自定义模板
              tplClauseLoaded = false;
              setDataListByTplClause();
            } else {
              // 系统内置模板
              dataList.value = [];
              // 新建时创建pane（clause_type=3为自定义条款）
              setDataListByDefaultClause();
            }
            if (dataList.value.length) {
              activeKey.value = dataList.value[0].key;
            }
          });
        }
      }
    };

    const updatePaneList = () => {
      const allRoomList = store.getters.checkedRoomList;
      const roomIds = allRoomList.map((item) => item.id);
      dataList.value.forEach((data) => {
        if (data.checkedHouse && data.checkedHouse.length) {
          let newHouse = [];
          data.checkedHouse.forEach((room) => {
            if (roomIds.includes(room.id)) {
              newHouse.push(room);
            } else {
              store.dispatch("SetPaneCheckedRoom", {
                type: "remove",
                clauseId: data.clause_id,
                roomIds: room.id,
              });
            }
          });
          data.checkedHouse = newHouse;
        }
      });
    };

    // 多楼宇 新增条款
    const addMultiPaneItem = (clause) => {
      // 根据 builds 来建立条款
      const roomList = store.getters.checkedRoomList;
      let builds = {};
      const addPanel = (checkedHouseList = []) => {
        count++;
        const paneItem = {
          ...clause,
          clause_id: clause.id,
          key: clause.attribute + "_" + count,
          title: clause.name,
          checkedHouse: checkedHouseList,
        };
        dataList.value.push(paneItem);
        store.dispatch("SetClauseContent", { type: "add", content: paneItem });
        store.dispatch("SetPaneCheckedRoom", {
          type: "add",
          clauseId: paneItem.clause_id,
          roomIds: paneItem.checkedHouse.map((it) => it.id),
        });
      };
      let result = store.getters.paneCheckedRoom[clause.id] || {};
      let surplusHouse = _.cloneDeep(roomList).filter((v) => !(result?.checkedIds || []).includes(v.id));
      // // 剩余房间
      surplusHouse.forEach((room) => {
        let buildId = room?.build_id || room?.extra?.build_id;
        if (builds[buildId]) {
          builds[buildId].push(room);
        } else {
          builds[buildId] = [room];
        }
      })
      if (Object.keys(builds).length) {
        // 有剩余房间
        Object.keys(builds).forEach((buildId) => {
          addPanel(builds[buildId])
        })
      } else {
        addPanel([])
      }
    };

    // 根据默认模板设置条款
    const setDataListByDefaultClause = () => {
      const defaultClause = store.getters.defaultClause;
      // 根据系统内置模板来增加条款
      count = 0;
      for (let item of clauseList.value) {
        if (item.clause_type != 3 && defaultClause.includes(item.attribute)) {
          if (multiBuild.value) {
            addMultiPaneItem(item);
          } else {
            addPaneItem(item);
          }
        }
      }
    };

    // 根据自定义模板设置条款
    let tplClauseLoaded = false;
    const setDataListByTplClause = () => {
      if (!tplClauseLoaded) {
        dataList.value = [];
        count = 0;
        if (multiBuild.value) {
          addMultiPaneItemByTpl();
        } else {
          addPaneItemByTpl();
        }
        tplClauseLoaded = true;
      }
    };

    // 根据用户自定义模板 新增多楼宇条款
    const addMultiPaneItemByTpl = () => {
      const roomList = store.getters.checkedRoomList;
      let builds = {};
      roomList.forEach((room) => {
        let buildId = room?.build_id || room?.extra?.build_id;
        if (builds[buildId]) {
          builds[buildId].push(room);
        } else {
          builds[buildId] = [room];
        }
      })
      const { multiple_clause } = tplContent.value;
      Object.keys(builds).forEach((buildId) => {
        for (let clause of multiple_clause) {
          count++;
          const { tempClauseInfo } = clause;
          const paneItem = {
            ...clause,
            clause_id: clause.id,
            key: clause.attribute + "_" + count,
            title: clause.name,
            checkedHouse: builds[buildId],
            bond_clause: {
              ...tempClauseInfo.bond_clause,
            },
            tax_clause: {
              ...tempClauseInfo.tax_clause,
            },
            multiple_clause: [...tempClauseInfo.normalClause],
          };
          if (tempClauseInfo.increaseClause) {
            paneItem.increment_clause = [...tempClauseInfo.increaseClause];
          }
          if (tempClauseInfo.discountClause) {
            paneItem.discount_clause = [...tempClauseInfo.discountClause];
          }
          store.dispatch("SetClauseContent", {
            type: "add",
            content: paneItem,
          });
          store.dispatch("SetPaneCheckedRoom", {
            type: "add",
            clauseId: paneItem.clause_id,
            roomIds: paneItem.checkedHouse.map((it) => it.id),
          });
          dataList.value.push(paneItem);
        }
      })
    };

    // 根据用户自定义模板 新增单楼宇条款
    const addPaneItemByTpl = () => {
      const { multiple_clause } = tplContent.value;
      const roomList = store.getters.checkedRoomList;
      for (let clause of multiple_clause) {
        count++;
        const { tempClauseInfo } = clause;
        let item = {
          ...clause,
          clause_id: clause.id,
          key: clause.attribute + "_" + count,
          title: clause.name,
          checkedHouse: [...roomList],
          bond_clause: {
            ...tempClauseInfo.bond_clause,
          },
          tax_clause: {
            ...tempClauseInfo.tax_clause,
          },
          multiple_clause: [...tempClauseInfo.normalClause],
        };
        if (tempClauseInfo.increaseClause) {
          item.increment_clause = [...tempClauseInfo.increaseClause];
        }
        if (tempClauseInfo.discountClause) {
          item.discount_clause = [...tempClauseInfo.discountClause];
        }
        store.dispatch("SetClauseContent", { type: "add", content: item });
        store.dispatch("SetPaneCheckedRoom", {
          type: "add",
          clauseId: item.clause_id,
          roomIds: item.checkedHouse.map((it) => it.id),
        });
        dataList.value.push(item);
      }
    };

    const $route = useRoute();
    watch(
      [
        () => store.getters.defaultClause,
        () => store.getters.checkedRoomList,
        () => store.getters.multiBuild,
      ],
      (
        [defaultClause, roomList, multiBuild],
        [preClause, preRoomList, preMultiBuild]
      ) => {
        console.log(
          "paneChange=============> defaultClause",
          toRaw(defaultClause),
          toRaw(preClause)
        );
        console.log(
          "paneChange=============> roomList",
          toRaw(roomList),
          toRaw(preRoomList)
        );
        console.log(
          "paneChange=============> multiBuild",
          toRaw(multiBuild),
          toRaw(preMultiBuild)
        );
        let clauseChange = (preClause?.length &&
          (preClause?.length != defaultClause?.length ||
            preClause[0] != defaultClause[0]));
        if (!$route.query.id) {
          if (useDraft.value && haveDraft.value) {
            if (
              multiBuild != preMultiBuild ||
              (preRoomList.length && roomListChange(preRoomList, roomList)) ||
              clauseChange
            ) {
              if (multiBuild || clauseChange) {
                //  跨楼宇情况下选择的房源变更 || 选择的房源变更
                getPaneList();
              } else {
                // 非跨楼宇情况下需要更新掉被删除的房源
                updatePaneList();
              }
              return;
            }
          } else {
            // 新增
            if (
              preClause.length != defaultClause.length ||
              preClause[0] != defaultClause[0] ||
              multiBuild ||
              !defaultClause.length
            ) {
              // 条款变更 || 跨楼宇选择房源 || 新增
              getPaneList();
              return;
            }
          }
        } else {
          // 编辑
          if (
            multiBuild != preMultiBuild ||
            (preRoomList.length && roomListChange(preRoomList, roomList)) ||
            clauseChange
          ) {
            if (multiBuild || clauseChange) {
              //  跨楼宇情况下选择的房源变更 || 选择的房源变更
              getPaneList();
            } else {
              // 非跨楼宇情况下需要更新掉被删除的房源
              updatePaneList();
            }
            return;
          }
        }
      }
    );

    const roomListChange = (preArr, arr) => {
      if (preArr.length != arr.length) {
        return true;
      }
      for (let item of preArr) {
        const idx = arr.findIndex((it) => it.id == item.id);
        if (idx == -1) {
          return true;
        }
      }
      return false;
    };

    // 条款选项
    const clauseList = ref([]);
    const getClauseList = () => {
      if ($route.query.contractType == "costContract") {
        store.dispatch("GetCostClause", 4).then((list) => {
          clauseList.value = list;
          const id = $route.query.id;
          if (!id && !isDraftFirst.value) {
            getPaneList();
          }
        });
      } else {
        store.dispatch("GetAllClause").then((list) => {
          clauseList.value = list;
          const id = $route.query.id;
          if (!id && !isDraftFirst.value) {
            getPaneList();
          }
        });
      }
    };

    watch([detailList, clauseList], ([detail, clause]) => {
      const { feeClause } = store.getters.addFormData;
      if (
        !dataList.value.length &&
        feeClause.expense_clause &&
        feeClause.expense_clause.length
      ) {
        dataList.value = [];
        feeClause.expense_clause.forEach((item, index) => {
          const existIndex = dataList.value.findIndex(
            (item2) => item.attribute == item2.attribute
          );
          if (existIndex == -1) {
            item.key = item.attribute + "_default";
          } else {
            count++;
            item.key = item.attribute + "_" + count;
          }
          item.name = item.title = item.clause_name;
          const detailData = detail.find((item2) => item2.id == item.id);
          if (detailData) {
            item.report_detail = detailData.report_detail;
          }
          if (detailData.use_bond) {
            item.use_bond = detailData.use_bond;
          }
          if (detailData.use_discount) {
            item.use_discount = detailData.use_discount;
          }
          if (detailData.use_incr) {
            item.use_incr = detailData.use_incr;
          }
          if (detailData.use_lease) {
            item.use_lease = detailData.use_lease;
          }
          item.cost_type = detailData.cost_type;
          item.cost_type_name = detailData.cost_type_name;
          item.cost_type_txt = detailData.cost_type_txt;
          item.checkedHouse = item.checked_build.room;
          // clauseList列表增加条款类型和租期条款字段
          if (clauseList.value.length) {
            clauseList.value.forEach((clause) => {
              if (item.clause_id == clause.id) {
                item.useBond = clause.use_bond;
                item.useLease = clause.use_lease;
              }
            });
          }
          dataList.value.push(item);
          store.dispatch("SetClauseContent", {
            type: "add",
            content: item,
          });
          store.dispatch("SetPaneCheckedRoom", {
            type: "add",
            clauseId: item.clause_id,
            roomIds: item.checkedHouse.map((it) => it.id),
          });

          if (index == 0) {
            activeKey.value = item.key;
          }
        });
      }
    });

    // 是否成本合同
    const isCostContract = computed(
      () => $route.query.contractType == "costContract"
    );

    // 验证表单
    let isFailed = false;
    let paneParamsContent = {};
    const contentTrigger = ref(0);
    const validateForm = () => {
      isFailed = false;
      paneParamsContent = {};
      contentTrigger.value++;
    };
    const handleValidateSuccess = (e) => {
      if (isFailed) {
        return;
      }
      const { key, content } = e;
      paneParamsContent[key] = content;
      console.log("条款项handleValidateSuccess ", e);
      if (Object.keys(paneParamsContent).length == dataList.value.length) {
        console.log("条款项所有表单验证成功 ", paneParamsContent);
        let paneContentList = [];
        let type = 0;
        for (let ck in paneParamsContent) {
          paneContentList.push(paneParamsContent[ck]);
          if (type == 0) {
            type = paneParamsContent[ck].attribute == "lease" ? "1" : "2";
          } else if (
            (type == 1 && paneParamsContent[ck].attribute == "property") ||
            (type == 2 && paneParamsContent[ck].attribute == "lease")
          ) {
            type = "1,2";
          }
        }
        store.dispatch("SetAddFormData", {
          key: "feeClause",
          data: { expense_clause: paneContentList, type },
        });
        console.log("条款项所有表单验证成功2 ", paneContentList);
        context.emit("success", { key: "feeClause" });
      }
    };
    const handleValidateFail = (e) => {
      console.log("条款项handleValidateFail ", e);
      if (isFailed) {
        return;
      }
      isFailed = true;
      const { key, msg } = e;
      activeKey.value = key;
      message.error(msg || "请完善当前条款的表单信息~");
      context.emit("fail", { key: "feeClause" });
    };

    const addPaneClick = (clause) => {
      if (multiBuild.value) {
        addMultiPaneItem(clause);
      } else {
        addPaneItem(clause);
      }
    };

    const init = () => {
      const id = $route.query.id;
      if (!id) {
        let draftInfo = utils.getStorage("contract_draft_info");
        if (draftInfo) {
          draftInfo = JSON.parse(draftInfo);
          if (draftInfo.feeClause) {
            isDraftFirst.value = true;
          }
        }
      }
      getClauseList();
    };

    init();

    watch(
      () => store.getters.validateTrigger,
      (val) => {
        if (val) {
          const step = store.getters.currentStep;
          if (step == 1) {
            validateForm();
          }
        }
      }
    );

    watch(
      () => store.getters.currentStep,
      (step) => {
        if (step == 1) {
          haveBeenInside.value = true;
        }
      }
    );

    watch(
      () => useDraft.value,
      (val) => {
        const id = $route.query.id;
        if (!id) {
          if (val == false) {
            isDraftFirst.value = false;
          }
        }

      }, {
        immediate: true,
      }
    );

    watch(
      () => dataList.value,
      (val) => {
        if (haveBeenInside.value && !$route.query.id) {
          // 继续保存草稿
          let draftInfo = utils.getStorage("contract_draft_info");
          if (!draftInfo) {
            draftInfo = {};
          } else {
            draftInfo = JSON.parse(draftInfo);
          }
          draftInfo.feeClause = _.cloneDeep(val);
          draftInfo.lastTime = utils.getDateString();
          utils.setStorage("contract_draft_info", JSON.stringify(draftInfo));
        }
      }, {
        deep: true,
      }
    );

    watch(
      () => store.getters.contractAddDraft,
      (val) => {
        if (val?.feeClause && !$route.query.id) {
          haveBeenInside.value = true; // 草稿初始化继续保存草稿
          isDraftFirst.value = false;
          haveDraft.value = true;
          // 为了避免第二步费用条款接口回应快慢问题处理 在基本信息 点击下一步时释放 慎用
          // 新增时草稿费用条款有值时赋值
          let sourceData = val.feeClause;
          dataList.value = [];
          store.dispatch("ClearClauseContent").then(() => {
            sourceData.forEach((item, index) => {
              store.dispatch("SetClauseContent", {
                type: "add",
                content: item,
              });
              store.dispatch("SetPaneCheckedRoom", {
                type: "add",
                clauseId: item.clause_id,
                roomIds: item.checkedHouse.map((it) => it.id),
              });
              dataList.value.push(item);
              if (index == 0) {
                activeKey.value = item.key;
              }
            })
          })
        }
      }
    );

    return {
      activeKey,
      clauseList,
      dataList,
      contentTrigger,
      onPaneEdit,
      handleValidateSuccess,
      handleValidateFail,
      addPaneClick,
    };
  },
});
</script>

<style lang="less" scoped></style>
